
`include "common_header.verilog"

//  *************************************************************************
//  File : mld_read_sm_40g_int_64b.vhd
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited.
//  Copyright (c) 2008 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Denis Poverennyy
//  info@morethanip.com
//  *************************************************************************
//  Description : MLD Read SM - inner part keeping track of marker occurence
//                and the 4:3 gearbox state depending on deskew FIFO read
//                activity.
//  Version     : $Id: mld_read_sm_40g_int_64b.v,v 1.1 2014/07/15 08:24:54 wt Exp $
//  *************************************************************************

module mld_read_sm_40g_int_64b (
   
        reset_rxclk,
        cgmii_rxclk,
        vl_intvl,
`ifdef MTIPPCS82_EEE_ENA 
        ram_period,
        read_adjust_req_long,
        desk_buf_am_rd,
`endif
        mld_rst,
        desk_buf_rd,


        desk_buf_data_mld_adv,
        desk_buf_data_mld_dval,
        desk_buf_marker_dval,
        desk_buf_marker_dval_nxt
                                );

input           reset_rxclk;                    //  async active high reset
input           cgmii_rxclk;                    //  ref clock
input   [15:0]  vl_intvl;                       //  test mode to speed up simulation        
`ifdef MTIPPCS82_EEE_ENA 
input           ram_period;                     //  if 1 - short RAM mode is set 
input           read_adjust_req_long;           //  if 1, desk_buf_marker_dval must be supressed 
output          desk_buf_am_rd;                 //  if 1, current read is marker read
`endif
input           mld_rst;                        //  software reset
input           desk_buf_rd;                    //  read occurs to Deskew Buffer
output          desk_buf_marker_dval_nxt;       //  next column will be a marker
output          desk_buf_data_mld_adv;          //  data valid without markers, advance (1 delayed, after memory output register)
output          desk_buf_data_mld_dval;         //  data valid without markers (2 delayed, after memory output register)
output          desk_buf_marker_dval;           //  current block is a marker (2 delayed, after memory output register)


reg             desk_buf_data_mld_dval; 
reg             desk_buf_marker_dval; 

reg     [15:0]  block_cnt;                      //  number of blocks sent per VL
reg             marker_dval_nxt;                //
reg             desk_buf_marker_dval_nxt;       //  one clock earlier than desk_buf_marker_dval
reg             desk_buf_data_mld_adv;          //  data valid without markers, advance (1 delayed, after memory output register)

`ifdef MTIPPCS82_EEE_ENA 
wire            desk_buf_am_rd;                 //  if 1, current read is marker read
reg             read_adjust_req_long_r;
`endif

//  General part
always @(posedge cgmii_rxclk or posedge reset_rxclk)
begin
        if (reset_rxclk == 1'b 1)
        begin
                block_cnt       <= 16'b 0;	//  count from 0 to 65536
                marker_dval_nxt <= 1'b 0;	
        end
        else
        begin
                if (mld_rst == 1'b 1)
                begin
                        block_cnt       <= 16'b 0;
                        marker_dval_nxt <= 1'b 0; 
                end
                else if (desk_buf_rd == 1'b 1 )
                begin
                        if ((block_cnt == vl_intvl )
`ifdef MTIPPCS82_EEE_ENA 
                        || (ram_period == 1'b1 && block_cnt[3:0] == 4'd 15 )
`endif                        
                                                                                        )
                        begin
                                block_cnt       <= 16'b 0;
                        end                
                        else
                        begin
                                block_cnt       <= block_cnt + 16'b 1;	
                        end

                       
                        if ( (block_cnt == (vl_intvl - 16'd 1) )
`ifdef MTIPPCS82_EEE_ENA 
                        || (ram_period == 1'b1 && block_cnt[3:0] == 4'd 14 )
`endif                        
                                                                                        )
                        begin
                                marker_dval_nxt <= 1'b 1;	
                        end                
                        else
                        begin
                                marker_dval_nxt <= 1'b 0;	
                        end                                              
                end           
        end
end




`ifdef MTIPPCS82_EEE_ENA 
assign desk_buf_am_rd =  desk_buf_rd == 1'b 1 && ram_period == 1'b1 && block_cnt[3:0] == 4'd 15;
`endif




//  data valid signals



always @(posedge cgmii_rxclk or posedge reset_rxclk)
begin
        if (reset_rxclk == 1'b 1)
        begin		
                desk_buf_marker_dval_nxt<= 1'b 0;
                desk_buf_marker_dval    <= 1'b 0;	
                desk_buf_data_mld_adv   <= 1'b 0;	
                desk_buf_data_mld_dval  <= 1'b 0;	
                `ifdef MTIPPCS82_EEE_ENA
                read_adjust_req_long_r     <= 1'b0;
                `endif

        end
        else
        begin
                if (mld_rst == 1'b 1)
                begin		
                        desk_buf_marker_dval_nxt<= 1'b 0;
                        `ifdef MTIPPCS82_EEE_ENA
                        read_adjust_req_long_r     <= 1'b0;
                        `endif
                        desk_buf_marker_dval    <= 1'b 0;		
                        desk_buf_data_mld_adv   <= 1'b 0;	
                        desk_buf_data_mld_dval  <= 1'b 0;	
                end
                else
                begin	
                        desk_buf_marker_dval_nxt<= desk_buf_rd & marker_dval_nxt;
                        `ifdef MTIPPCS82_EEE_ENA
                        read_adjust_req_long_r     <= read_adjust_req_long;
                        `endif 	                        	
                        desk_buf_marker_dval    <= desk_buf_marker_dval_nxt `ifdef MTIPPCS82_EEE_ENA & ~read_adjust_req_long_r `endif;	
                        desk_buf_data_mld_adv   <= desk_buf_rd & !marker_dval_nxt;        // advance
                        desk_buf_data_mld_dval  <= desk_buf_data_mld_adv;	

                end
      end
end










endmodule // module mld_read_sm_40g_int_64b

